package com.lzj.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lzj.admin.model.CountResultModel;
import com.lzj.admin.pojo.Customer;
import com.lzj.admin.pojo.Goods;
import com.lzj.admin.pojo.SaleList;
import com.lzj.admin.mapper.SaleListMapper;
import com.lzj.admin.pojo.SaleListGoods;
import com.lzj.admin.query.SaleListQuery;
import com.lzj.admin.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzj.admin.utils.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 销售单表 服务实现类
 * </p>
 *
 * @author luoyoumou
 * @date 2022-12-15
 */
@Service
public class SaleListServiceImpl extends ServiceImpl<SaleListMapper, SaleList> implements ISaleListService {

    @Resource
    private IGoodsService goodsService;

    @Resource
    private ISaleListGoodsService saleListGoodsService;

    @Resource
    private IGoodsTypeService goodsTypeService;

    @Resource
    private ICustomerService customerService;

    @Override
    public String getNextSaleNumber() {
        try {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("XS");
            stringBuffer.append(DateUtil.getCurrentDateStr());
            String saleNumber = this.baseMapper.getNextSaleNumber();
            if (null != saleNumber) {
                stringBuffer.append(StringUtil.formatCode(saleNumber));
            } else {
                stringBuffer.append("0001");
            }
            return stringBuffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void saveSaleList( SaleList saleList, List<SaleListGoods> slgList) {
        AssertUtil.isTrue(null == saleList.getCustomerId() ,"请选择客户！");
        Customer customer = customerService.getById(saleList.getCustomerId());
        AssertUtil.isTrue( null == customer,"客户不存在！");
        AssertUtil.isTrue(CollectionUtils.isEmpty(slgList),"请添加商品！");
        System.out.println("CustomerID: "+customer.getId());
        AssertUtil.isTrue(null == saleList.getAmountPaid() || 0 >= saleList.getAmountPaid() ,"实付金额 必须 >0 ！");
        saleList.setCreateDate(new Date());
        AssertUtil.isTrue(!(this.save(saleList)), "记录添加失败!");
        SaleList temp = this.getOne(new QueryWrapper<SaleList>().eq("sale_number", saleList.getSaleNumber()));
        slgList.forEach(slg -> {
            AssertUtil.isTrue(null == slg.getNum()|| 1 > slg.getNum(),"请检查：每件商品的 数量 必须 >=1 ！");
            slg.setSaleListId(temp.getId());
            slg.setFpyName(PinYinUtil.getFirstSpell(slg.getName()));
            Goods goods = goodsService.getById(slg.getGoodsId());
            // 检查库存
            AssertUtil.isTrue(goods.getInventoryQuantity()< slg.getNum(),"商品 "+ goods.getName() +" 的库存数量不足，操作失败！");
            goods.setInventoryQuantity(goods.getInventoryQuantity() - slg.getNum());
            goods.setState(2);
            AssertUtil.isTrue(!(goodsService.updateById(goods)), "记录添加失败!");
            AssertUtil.isTrue(!(saleListGoodsService.save(slg)), "记录添加失败!");
        });
        Date saleDate = saleList.getSaleDate();
        System.out.println("saleDate: "+saleDate);
        Date customerLastTradeDate = customer.getLastTradeDate();
        if(customerLastTradeDate.before(saleDate)){
            customer.setLastTradeDate(new Date());
            AssertUtil.isTrue(!(customerService.updateById(customer)), "记录添加失败!");
        }
    }

    @Override
    public Map<String, Object> saleList(SaleListQuery saleListQuery) {
        IPage<SaleList> page = new Page<SaleList>(saleListQuery.getPage(), saleListQuery.getLimit());
        page = this.baseMapper.saleList(page, saleListQuery);
        return PageResultUtil.getResult(page.getTotal(), page.getRecords());
    }


    /**
     * 销售表单的实现
     * @param id
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void updateSaleListState(Integer id) {
        //通过id，判断销售记录是否存在
        SaleList saleList =this.getById(id);
        AssertUtil.isTrue(null == saleList,"待结算的销售单记录不存在!");
        //判断交易状态，getState()==1提示已经支付
        AssertUtil.isTrue(saleList.getState()==1,"该销售单已结算!");
        //更新结算状态
        saleList.setState(1);
        //调用父类更新方法，根据id执行更新，取反结果为真，更新失败
        AssertUtil.isTrue(!(this.updateById(saleList)),"销售单结算失败!");
    }

    /**
     * 商品销售统计,查总数，查当前页列表
     * @param saleListQuery
     * @return
     */
    @Override
    public Map<String, Object> countSale(SaleListQuery saleListQuery) {
        /**
         * 分页查询
         *   查总数
         *   查当前页列表
         */
        if(null !=saleListQuery.getTypeId()){
            List<Integer> typeIds= goodsTypeService.queryAllSubTypeIdsByTypeId(saleListQuery.getTypeId());
            saleListQuery.setTypeIds(typeIds);
        }
        if( null != saleListQuery.getTypeName()){
            saleListQuery.setTypeIds(goodsTypeService.queryAllSubTypeIdsByTypeId(saleListQuery.getTypeName()));
        }
        /**
         *  page
         *    1-->0
         *    2-->10
         *    3-->20
         */
        saleListQuery.setIndex((saleListQuery.getPage()-1)*saleListQuery.getLimit());
        Long count  = this.baseMapper.countSaleTotal(saleListQuery);
        List<CountResultModel> list =this.baseMapper.saleListQueryList(saleListQuery);
        return PageResultUtil.getResult(count,list);
    }

    @Override
    public List<Map<String, Object>> countDaySale(String begin, String end) {
        return this.baseMapper.countDaySale(begin,end);
    }

    @Override
    public List<Map<String, Object>> countMonthSale(String begin, String end) {
        return this.baseMapper.countMonthSale(begin,end);
    }

    /**
     * 销售单据的删除 需要添加条件判断？
     * 比如： 未付款 或 未发货 的，可以直接删除，但删除的同时 商品相关库存需要 添加进来？ 如果已经付款的，不能删除，只能走退货  待解决
     * 目前的删除动作，是表记录都没有了，很暴力！
     * @param id
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void deleteSaleList(Integer id) {
        AssertUtil.isTrue(!(saleListGoodsService.remove(new QueryWrapper<SaleListGoods>().eq("sale_list_id",id))),
                "记录删除失败!");
        AssertUtil.isTrue(!(this.removeById(id)),"记录删除失败!");
    }

}
